<?php 
/**
 * Класс, который реализовует базовые методы менеджемна даних в таблице
 *
 */

class FRM_Db_Table extends FRM_Db_Table_Abstract
{
	protected $data;

	public $formTemplate = 'One';

	protected $formRelations = array();

	protected $postPart;

	protected $fields = array();

	public function setFields($fileds){
		$this->fields = $fileds;
		return $this;
	}

	public function addField($filed){
		$this->fields[] = $filed;
		return $this;
	}

	public function setRelations($formRelations){
		$this->formRelations = $formRelations;
		return $this;
	}

	public function getRelations(){
		return $this->formRelations;
	}

	public function addRelation($formRelation){
		$this->formRelations[] = $formRelation;
		return $this;
	}

	public function getFields(){
		return $this->fields;
	}

	public function setPostPart($postPart){
		$this->postPart = $postPart;
		return $this;
	}

	/**
	 * Наздачить переменную $data
	 *
	 * @param array $data
	 */
	public function setData($data){
		$this->data = $data;
	}

	/**
	 * Уничтожить переменную $data
	 *
	 */
	public function unsetData(){
		$this->data = null;
	}


	/**
     * Назначить значение ключа $key
     *
     * @param string $key
     * @param mixed $value
     */
	private function equalsValue($key, $value){
		$this->data[$key] = $value;
	}

	/**
     * Получить значение ключа $key
     */
	private function getValue($key){
		return $this->data[$key];
	}

	/**
	 * Валидация
	 *
	 * @return boolean
	 */
	private function isValid(){
		/*
		if(!is_null($this->validator)){
		$this->validator->setData($this->data);
		return $this->validator->isValidWhole();
		}*/
		return true;
	}

	/**
	 * Добавление записи в базу
	 *
	 * @return zend_db_table_row
	 */
	public function insertData($data=null){
		// Загружаем даные с поста, если они пришли пустые
		if(is_null($data)){
			if(!$this->data){
				$this->loadPost();
			}
			$data = $this->data;
		}

		$dataTmp = $data;
		foreach ($data as $k=>$v){
			if(is_array($v)){
				unset($dataTmp[$k]);
			}
		}
		$data = $dataTmp;
		
		//Запускаем тригер
		$d = $this->before($data);
		if(isset($d) && !is_null($d)){
			$data = $d;
		}


		//Запускаем тригер
		$this->beforeInsert();

		//Запускаем валидацию
		if($this->isValid()){

			if(empty($data[$this->keyField])){
				unset($data[$this->keyField]);
			}

			//Вставляем дание в базу
			//$id = 0;
			$id = $this->insert($data);
			//$id=100;
			//Обновляем размещение (перемещаяем в конець)
			if(isset($data[$this->orderField])){
				$this->updatField($this->orderField, $id, $id);
			}

			//Запускаем тригер
			$this->afterInsert($id);
			//Запускаем тригер
			$this->after($id);


			return $id;
		}
		return null;
	}




	/**
     * Изменения записи в таблице
     *
     * @return zend_db_table_row
     */
	public function updateData($data=null){
		// Загружаем даные с поста, если они пришли пустые
		if(is_null($data)){
			if(!$this->data){
				$this->loadPost();
			}
			$data = $this->data;
		}
		
		$dataTmp = $data;
		foreach ($data as $k=>$v){
			if(is_array($v)){
				unset($dataTmp[$k]);
			}
		}
		$data = $dataTmp;
		
		$id = $data[$this->keyField];

		///Запускаем тригер
		$d = $this->before($data);
		if(isset($d) && !is_null($d)){
			$data = $d;
		}
		//Запускаем тригер
		$this->beforeUpdate($id);

		//Запускаем валидацию
		if($this->isValid()){

			//Удалаем ид с масива
			if(empty($data[$this->keyField])){
				unset($data[$this->keyField]);
			}
			//Удаляем ордер с масива
			unset($data[$this->orderField]);

			$where = null;

			if(count($this->_primary)>1){
				$where = '';
				foreach ($this->_primary as $key){
					if($where){
						$where .=' AND ';
					}
					$where .= $this->getAdapter()->quoteInto("$key = ?", $data[$key]);
				}
			}else {
				$where = $this->getAdapter()->quoteInto("$this->keyField = ?", $id);
			}

			//Изменяем данные
			$this->update($data, $where);

			//Запускаем тригер
			$this->afterUpdate($id);
			//Запускаем тригер
			$this->after($id);

			//Уничтожаем дание
			$this->unsetData();

			//Возращаем вставленую запись целиком
			return $id;
		}
		return null;
	}

	public function saveData(){
		if(!$this->data){
			$this->loadPost();
		}
		if(!isset($this->data[0])){
			$this->data = array($this->data);
		}

		$mydata = $this->data;

		foreach ($mydata as $data){
			//
//print_r($data);print"<br>";
			$row = null;


			if(!empty($data[$this->keyField])){
				if(count($this->_primary)>1){
					$row = 	$this->find($data[$this->_primary[1]], $data[$this->_primary[2]])->current();
				}else{
					$row = 	$this->find($data[$this->keyField])->current();
				}
			}

			if(is_null($row)){
				$id = $this->insertData($data);
				//$id = 10;
			}else{
				$id = $this->updateData($data);
				//$id = 10;
			}

			$ids[]=$id;
		}
		//Уничтожаем дание
		$this->unsetData();

		if(!count($ids)){
			return null;
		}

		if(count($ids) ==1){
			return $ids[0];
		}

	}

	/**
	 * Удаляем запись
	 *
	 * @param int $id
	 */
	public function deleteData($id){
		///Запускаем тригер
		$this->beforeDelete($id);

		//Удаляем
		$this->delete($this->getAdapter()->quoteInto("$this->keyField = ?", $id));

		///Запускаем тригер
		$this->afterDelete($id);
	}

	/**
	 * Показываем запись
	 *
	 * @param unknown_type $id
	 */
	public function show($id){
		$this->updatField($this->showField, 1, $id);
	}

	/**
	 * Прячем запись
	 *
	 * @param unknown_type $id
	 */
	public function hide($id){
		$this->updatField($this->showField, 0, $id);
	}

	/**
	 * Перемещаем текущую вверх на одину запись
	 *
	 * @param int $id
	 */
	public function up($id){
		//Получаем текушее размешение
		$order =  (int)$this->find($id)->current()->__get($this->orderField);

		$a  = $this->getAdapter();
		
		$where = $a->quoteInto("`$this->orderField` < ?", $order);
		
		if(!is_null($this->currentWhere)){
			$where = array($this->currentWhere, $where);
		}
		
		//print_r($where);
		
		//Получаем запить что више
		$temp=$this->currentSelect;
		if(isset($this->currentSelect)){
			$this->currentSelect=null;
		}
		$upRow = $this->getRowByParam($where, "$this->orderField DESC");

		//Меняем местами если не пустая записть что віше
		if(!empty($upRow[$this->keyField]) && !empty($upRow[$this->orderField]))
		{
			$this->updatField($this->orderField, $upRow[$this->orderField], $id);
			$this->updatField($this->orderField, $order, $upRow[$this->keyField]);
		}
		$this->currentSelect = $temp;
	}

	/**
	 * Перемещаем текущую вниз на одину запись
	 *
	 * @param int $id
	 */
	public function down($id){
		//Получаем текушее размешение
		$order =  (int)$this->find($id)->current()->__get($this->orderField);
		
		$a  = $this->getAdapter();
		
		$where = $a->quoteInto("`$this->orderField` > ?", $order);
		
		if(!is_null($this->currentWhere)){
			$where = array($this->currentWhere, $where);
		}
		
		//print_r($where);
		
		$temp=$this->currentSelect;

		//Получаем запить что ниже
		if(isset($this->currentSelect)){
			$this->currentSelect=null;
		}
		$downRow = $this->getRowByParam($where, "$this->orderField");

		//Меняем местами если не пустая записть что ниже
		if(!empty($downRow[$this->keyField]) && !empty($downRow[$this->orderField]))
		{
			$this->updatField($this->orderField, $downRow[$this->orderField], $id);
			$this->updatField($this->orderField, $order, $downRow[$this->keyField]);
		}
		$this->currentSelect = $temp;
	}

	/**
     * Получаем данные с пост
     *
     */
	private function loadPost()
	{
		//print_r($_POST);
		//print_r($this->_cols);
		if(!is_null($this->postPart) && isset($this->formRelations[$this->postPart]) )
		{
			$post = (!is_null($this->postPart) && isset($this->formRelations[$this->postPart]) && isset($_POST[$this->postPart]))?$_POST[$this->postPart]:null;

			if(!is_null($post) && is_array($post) &&  isset($this->formRelations[$this->postPart]['key'])){
				$this->data = array();
				foreach ($post as $k=>$v){

					$v[$this->formRelations[$this->postPart]['key']] = $k;
					if(isset($this->formRelations[$this->postPart]['extra']) && is_array($this->formRelations[$this->postPart]['extra'])){
						foreach ($this->formRelations[$this->postPart]['extra'] as $key=>$value){
							$v[$key]=$value;
						}
					}
					//print_r($v);
					$data = array();
					foreach ($this->_cols as $col) {
						if(FRM_Filter_Post::has($col, $v)){
							$data[$col] = FRM_Filter_Post::raw($col, $v);
						}
					}

					//print_r($data);
					$this->data[] = $data;

				}
				//print_r($this->data);
				return;
			}
			exit();
		}
		foreach ($this->_cols as $col) {
			if(FRM_Filter_Post::has($col, $this->postPart)){
				$this->data[$col] = FRM_Filter_Post::raw($col, $this->postPart);
			}
		}
	}



	//Тригера

	public function before($data){}
	public function beforeInsert(){}
	public function beforeUpdate($id){}
	public function beforeDelete($id){}
	public function after($id){}
	public function afterInsert($id){}
	public function afterUpdate($id){}
	public function afterDelete($id){}

}